package job_types

import (
	"context"
	"log"

	"gitlab.ctyuncdn.cn/tai/infra/cloud-controller/internal/job_manager"
	"gitlab.ctyuncdn.cn/tai/infra/cloud-controller/pkg/mysql"
)

// Example demonstrates how to use job type implementations
func Example() {
	// Create a mock database (in real usage, this would be a real database)
	// For this example, we'll use a simple in-memory implementation
	db := &MockDatabase{}

	// Create a job manager
	manager := job_manager.NewBaseJobManager(db)

	// Register all job type handlers
	if err := RegisterAllJobTypes(manager); err != nil {
		log.Fatalf("Failed to register job types: %v", err)
	}

	// Start the job manager
	if err := manager.Start(); err != nil {
		log.Fatalf("Failed to start job manager: %v", err)
	}
	defer manager.Stop()

	// Create a notebook job
	notebookJob := &mysql.Job{
		JobID:      "notebook-example",
		JobType:    string(job_manager.JobTypeNotebook),
		Priority:   1,
		Parameters: `{"notebook_path": "/workspace/example.ipynb", "port": 8888}`,
	}

	if err := manager.CreateJob(context.Background(), notebookJob); err != nil {
		log.Printf("Failed to create notebook job: %v", err)
	}

	// Create a training job
	trainingJob := &mysql.Job{
		JobID:      "training-example",
		JobType:    string(job_manager.JobTypeTraining),
		Priority:   2,
		Parameters: `{"script_path": "/workspace/train.py", "data_path": "/data", "model_path": "/models", "epochs": 100}`,
	}

	if err := manager.CreateJob(context.Background(), trainingJob); err != nil {
		log.Printf("Failed to create training job: %v", err)
	}

	// Create a batch job
	batchJob := &mysql.Job{
		JobID:      "batch-example",
		JobType:    string(job_manager.JobTypeBatch),
		Priority:   3,
		Parameters: `{"script_path": "/workspace/process.py", "input_path": "/input", "output_path": "/output", "parallelism": 4}`,
	}

	if err := manager.CreateJob(context.Background(), batchJob); err != nil {
		log.Printf("Failed to create batch job: %v", err)
	}

	// Start the jobs
	if err := manager.StartJob(context.Background(), "notebook-example"); err != nil {
		log.Printf("Failed to start notebook job: %v", err)
	}

	if err := manager.StartJob(context.Background(), "training-example"); err != nil {
		log.Printf("Failed to start training job: %v", err)
	}

	if err := manager.StartJob(context.Background(), "batch-example"); err != nil {
		log.Printf("Failed to start batch job: %v", err)
	}

	// Get job status
	status, err := manager.GetJobStatus(context.Background(), "notebook-example")
	if err != nil {
		log.Printf("Failed to get job status: %v", err)
	} else {
		log.Printf("Notebook job status: %s - %s", status.Status, status.Message)
	}

	// Get job manager stats
	stats := manager.GetStats()
	log.Printf("Job manager stats: %+v", stats)
}

// MockDatabase is a simple mock database for the example
type MockDatabase struct {
	jobs map[string]*mysql.Job
}

func (m *MockDatabase) Create(value interface{}) job_manager.DatabaseResult {
	if job, ok := value.(*mysql.Job); ok {
		if m.jobs == nil {
			m.jobs = make(map[string]*mysql.Job)
		}
		m.jobs[job.JobID] = job
	}
	return &MockDatabaseResult{}
}

func (m *MockDatabase) Model(value interface{}) job_manager.DatabaseInterface {
	return m
}

func (m *MockDatabase) Where(query interface{}, args ...interface{}) job_manager.DatabaseInterface {
	return m
}

func (m *MockDatabase) Order(value interface{}) job_manager.DatabaseInterface {
	return m
}

func (m *MockDatabase) First(dest interface{}) job_manager.DatabaseResult {
	if job, ok := dest.(*mysql.Job); ok {
		if m.jobs != nil {
			for _, j := range m.jobs {
				*job = *j
				break
			}
		}
	}
	return &MockDatabaseResult{}
}

func (m *MockDatabase) Find(dest interface{}) job_manager.DatabaseResult {
	return &MockDatabaseResult{}
}

func (m *MockDatabase) Updates(values interface{}) job_manager.DatabaseResult {
	return &MockDatabaseResult{}
}

func (m *MockDatabase) Error() error {
	return nil
}

type MockDatabaseResult struct{}

func (m *MockDatabaseResult) Error() error {
	return nil
}
